using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using TwinCAT.Ads;


namespace PoolHeater
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class FrmMain : System.Windows.Forms.Form
	{
		internal System.Windows.Forms.Button BtnDeleteNotifications;
		internal System.Windows.Forms.Button BtnAddNotifications;
		internal System.Windows.Forms.Button BtnWrite;
        internal System.Windows.Forms.Button BtnRead;
        internal System.Windows.Forms.GroupBox GroupBox1;
		internal System.Windows.Forms.TextBox TbHeaterState;
		internal System.Windows.Forms.Label LabLabel1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		//PLC variable handles
		private int _hdint1;
		private int _hState;
        private int _hPumpState; 
		private int _husint1;
		private int _hlreal1;
		private int _hstr1;
		private int _hstr2;
		private int _hcomplexStruct;
        private int _hHeater1;
        private int _hHeater2;
        private int _hHeater3;

		private ArrayList _arrNotificationHandles;
        private Label _labLabel2;
        private Label _labLabel3;
        private Label _labHeater1;
        private Label _labHeater2;
        private Label _labHeater3;
        private TextBox _txtPoolHeaterState;
        private TextBox _txtTextBox2;
		
		private TcAdsClient _adsClient;

	    private bool _boPoolHeaterState;
	    private bool _boPumpState;
	    private float _fTest2;
        
        private ProgressBar _barHeater1;
        private ProgressBar _barHeater2;
        private ProgressBar _barHeater3;

        private int _inProgressBarMax;
        private Button _btnPumpState;
        private Label labRelais;
        private int _inProgressBarMin;
        

		public FrmMain()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.BtnDeleteNotifications = new System.Windows.Forms.Button();
            this.BtnAddNotifications = new System.Windows.Forms.Button();
            this.BtnWrite = new System.Windows.Forms.Button();
            this.BtnRead = new System.Windows.Forms.Button();
            this.GroupBox1 = new System.Windows.Forms.GroupBox();
            this.TbHeaterState = new System.Windows.Forms.TextBox();
            this.LabLabel1 = new System.Windows.Forms.Label();
            this._labLabel2 = new System.Windows.Forms.Label();
            this._labLabel3 = new System.Windows.Forms.Label();
            this._txtPoolHeaterState = new System.Windows.Forms.TextBox();
            this._txtTextBox2 = new System.Windows.Forms.TextBox();
            this._barHeater1 = new System.Windows.Forms.ProgressBar();
            this._barHeater2 = new System.Windows.Forms.ProgressBar();
            this._barHeater3 = new System.Windows.Forms.ProgressBar();
            this._labHeater1 = new System.Windows.Forms.Label();
            this._labHeater2 = new System.Windows.Forms.Label();
            this._labHeater3 = new System.Windows.Forms.Label();
            this._btnPumpState = new System.Windows.Forms.Button();
            this.labRelais = new System.Windows.Forms.Label();
            this.GroupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // BtnDeleteNotifications
            // 
            this.BtnDeleteNotifications.Location = new System.Drawing.Point(472, 112);
            this.BtnDeleteNotifications.Name = "BtnDeleteNotifications";
            this.BtnDeleteNotifications.Size = new System.Drawing.Size(112, 23);
            this.BtnDeleteNotifications.TabIndex = 13;
            this.BtnDeleteNotifications.Text = "Delete Notifications";
            this.BtnDeleteNotifications.Click += new System.EventHandler(this.BtnDeleteNotificationsClick);
            // 
            // BtnAddNotifications
            // 
            this.BtnAddNotifications.Location = new System.Drawing.Point(472, 80);
            this.BtnAddNotifications.Name = "BtnAddNotifications";
            this.BtnAddNotifications.Size = new System.Drawing.Size(112, 23);
            this.BtnAddNotifications.TabIndex = 12;
            this.BtnAddNotifications.Text = "Add Notifications";
            this.BtnAddNotifications.Click += new System.EventHandler(this.BtnAddNotificationsClick);
            // 
            // BtnWrite
            // 
            this.BtnWrite.Location = new System.Drawing.Point(472, 48);
            this.BtnWrite.Name = "BtnWrite";
            this.BtnWrite.Size = new System.Drawing.Size(112, 23);
            this.BtnWrite.TabIndex = 11;
            this.BtnWrite.Text = "Write";
            this.BtnWrite.Click += new System.EventHandler(this.BtnWriteClick);
            // 
            // BtnRead
            // 
            this.BtnRead.Location = new System.Drawing.Point(472, 16);
            this.BtnRead.Name = "BtnRead";
            this.BtnRead.Size = new System.Drawing.Size(112, 23);
            this.BtnRead.TabIndex = 10;
            this.BtnRead.Text = "Read";
            this.BtnRead.Click += new System.EventHandler(this.BtnReadClick);
            // 
            // GroupBox1
            // 
            this.GroupBox1.Controls.Add(this.TbHeaterState);
            this.GroupBox1.Controls.Add(this.LabLabel1);
            this.GroupBox1.Location = new System.Drawing.Point(8, 8);
            this.GroupBox1.Name = "GroupBox1";
            this.GroupBox1.Size = new System.Drawing.Size(168, 152);
            this.GroupBox1.TabIndex = 7;
            this.GroupBox1.TabStop = false;
            this.GroupBox1.Text = "Primitive Types";
            // 
            // TbHeaterState
            // 
            this.TbHeaterState.Location = new System.Drawing.Point(64, 27);
            this.TbHeaterState.Name = "TbHeaterState";
            this.TbHeaterState.Size = new System.Drawing.Size(88, 20);
            this.TbHeaterState.TabIndex = 1;
            // 
            // LabLabel1
            // 
            this.LabLabel1.Location = new System.Drawing.Point(8, 27);
            this.LabLabel1.Name = "LabLabel1";
            this.LabLabel1.Size = new System.Drawing.Size(50, 16);
            this.LabLabel1.TabIndex = 0;
            this.LabLabel1.Text = "bEnable:";
            // 
            // _labLabel2
            // 
            this._labLabel2.AutoSize = true;
            this._labLabel2.Location = new System.Drawing.Point(393, 186);
            this._labLabel2.Name = "_labLabel2";
            this._labLabel2.Size = new System.Drawing.Size(60, 13);
            this._labLabel2.TabIndex = 14;
            this._labLabel2.Text = "PoolHeater";
            // 
            // _labLabel3
            // 
            this._labLabel3.AutoSize = true;
            this._labLabel3.Location = new System.Drawing.Point(393, 219);
            this._labLabel3.Name = "_labLabel3";
            this._labLabel3.Size = new System.Drawing.Size(60, 13);
            this._labLabel3.TabIndex = 15;
            this._labLabel3.Text = "PoolHeater";
            // 
            // _txtPoolHeaterState
            // 
            this._txtPoolHeaterState.Location = new System.Drawing.Point(472, 183);
            this._txtPoolHeaterState.Name = "_txtPoolHeaterState";
            this._txtPoolHeaterState.Size = new System.Drawing.Size(112, 20);
            this._txtPoolHeaterState.TabIndex = 16;
            // 
            // _txtTextBox2
            // 
            this._txtTextBox2.Location = new System.Drawing.Point(472, 216);
            this._txtTextBox2.Name = "_txtTextBox2";
            this._txtTextBox2.Size = new System.Drawing.Size(112, 20);
            this._txtTextBox2.TabIndex = 17;
            // 
            // _barHeater1
            // 
            this._barHeater1.Location = new System.Drawing.Point(113, 256);
            this._barHeater1.Name = "_barHeater1";
            this._barHeater1.Size = new System.Drawing.Size(471, 23);
            this._barHeater1.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
            this._barHeater1.TabIndex = 18;
            // 
            // _barHeater2
            // 
            this._barHeater2.Location = new System.Drawing.Point(113, 306);
            this._barHeater2.Name = "_barHeater2";
            this._barHeater2.Size = new System.Drawing.Size(471, 23);
            this._barHeater2.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
            this._barHeater2.TabIndex = 19;
            // 
            // _barHeater3
            // 
            this._barHeater3.Location = new System.Drawing.Point(113, 355);
            this._barHeater3.Name = "_barHeater3";
            this._barHeater3.Size = new System.Drawing.Size(471, 23);
            this._barHeater3.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
            this._barHeater3.TabIndex = 20;
            // 
            // _labHeater1
            // 
            this._labHeater1.AutoSize = true;
            this._labHeater1.Location = new System.Drawing.Point(16, 256);
            this._labHeater1.Name = "_labHeater1";
            this._labHeater1.Size = new System.Drawing.Size(45, 13);
            this._labHeater1.TabIndex = 21;
            this._labHeater1.Text = "Heater1";
            // 
            // _labHeater2
            // 
            this._labHeater2.AutoSize = true;
            this._labHeater2.Location = new System.Drawing.Point(16, 306);
            this._labHeater2.Name = "_labHeater2";
            this._labHeater2.Size = new System.Drawing.Size(45, 13);
            this._labHeater2.TabIndex = 22;
            this._labHeater2.Text = "Heater2";
            // 
            // _labHeater3
            // 
            this._labHeater3.AutoSize = true;
            this._labHeater3.Location = new System.Drawing.Point(16, 355);
            this._labHeater3.Name = "_labHeater3";
            this._labHeater3.Size = new System.Drawing.Size(45, 13);
            this._labHeater3.TabIndex = 23;
            this._labHeater3.Text = "Heater3";
            // 
            // _btnPumpState
            // 
            this._btnPumpState.BackColor = System.Drawing.Color.Red;
            this._btnPumpState.Location = new System.Drawing.Point(235, 28);
            this._btnPumpState.Name = "_btnPumpState";
            this._btnPumpState.Size = new System.Drawing.Size(48, 42);
            this._btnPumpState.TabIndex = 24;
            this._btnPumpState.Text = "Pumpe";
            this._btnPumpState.UseVisualStyleBackColor = false;
            this._btnPumpState.Click += new System.EventHandler(this.BtnPumpStateClick);
            // 
            // labRelais
            // 
            this.labRelais.AutoSize = true;
            this.labRelais.Location = new System.Drawing.Point(215, 80);
            this.labRelais.Name = "labRelais";
            this.labRelais.Size = new System.Drawing.Size(86, 13);
            this.labRelais.TabIndex = 25;
            this.labRelais.Text = "Pumpe EIN AUS";
            // 
            // FrmMain
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(592, 418);
            this.Controls.Add(this.labRelais);
            this.Controls.Add(this._btnPumpState);
            this.Controls.Add(this._labHeater3);
            this.Controls.Add(this._labHeater2);
            this.Controls.Add(this._labHeater1);
            this.Controls.Add(this._barHeater3);
            this.Controls.Add(this._barHeater2);
            this.Controls.Add(this._barHeater1);
            this.Controls.Add(this._txtTextBox2);
            this.Controls.Add(this._txtPoolHeaterState);
            this.Controls.Add(this._labLabel3);
            this.Controls.Add(this._labLabel2);
            this.Controls.Add(this.BtnDeleteNotifications);
            this.Controls.Add(this.BtnAddNotifications);
            this.Controls.Add(this.BtnWrite);
            this.Controls.Add(this.BtnRead);
            this.Controls.Add(this.GroupBox1);
            this.Name = "FrmMain";
            this.Text = "PoolHeater";
            this.Closing += new System.ComponentModel.CancelEventHandler(this.FrmMainClosing);
            this.Load += new System.EventHandler(this.FrmMainLoad);
            this.GroupBox1.ResumeLayout(false);
            this.GroupBox1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{		
			Application.Run(new FrmMain());
		}

		private void FrmMainLoad(object sender, System.EventArgs e)
		{
			_adsClient = new TcAdsClient();
			_arrNotificationHandles = new ArrayList();
			try
			{
				_adsClient.Connect(801);
                _adsClient.AdsNotificationEx+=new AdsNotificationExEventHandler(AdsClientAdsNotificationEx);
				BtnDeleteNotifications.Enabled = false;

				//create handles for the PLC variables;
				_hState = _adsClient.CreateVariableHandle(".g_stState.bEnable");
			    _hPumpState = _adsClient.CreateVariableHandle(".g_stState.bEnablePumpManually");
			    _hHeater1 = _adsClient.CreateVariableHandle(".g_stTemperature.farrHeater[1]");
                _hHeater2 = _adsClient.CreateVariableHandle(".g_stTemperature.farrHeater[2]");
                _hHeater3 = _adsClient.CreateVariableHandle(".g_stTemperature.farrHeater[3]");

                
	            _arrNotificationHandles.Clear();

                _arrNotificationHandles.Add(_adsClient.AddDeviceNotificationEx(".g_stState.bEnable", AdsTransMode.OnChange, 100, 0, _hState, typeof(Boolean)));
                _arrNotificationHandles.Add(_adsClient.AddDeviceNotificationEx(".g_stState.bEnablePumpManually", AdsTransMode.OnChange, 100, 0, _hPumpState, typeof(Boolean)));
                _arrNotificationHandles.Add(_adsClient.AddDeviceNotificationEx(".g_stTemperature.farrHeater[1]", AdsTransMode.OnChange, 100, 0, _hHeater1, typeof(float)));
                _arrNotificationHandles.Add(_adsClient.AddDeviceNotificationEx(".g_stTemperature.farrHeater[2]", AdsTransMode.OnChange, 100, 0, _hHeater2, typeof(float)));
                _arrNotificationHandles.Add(_adsClient.AddDeviceNotificationEx(".g_stTemperature.farrHeater[3]", AdsTransMode.OnChange, 100, 0, _hHeater3, typeof(float)));
                
                //hcomplexStruct = adsClient.CreateVariableHandle("MAIN.ComplexStruct1");

			    _inProgressBarMin = 100;
			    _inProgressBarMax = 300;

                SetProgressBar(_inProgressBarMax,_inProgressBarMin);

			}

		        catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

	    private void SetProgressBar(int inMax, int inMin)
	    {
	        _barHeater1.Minimum = inMin;
	        _barHeater1.Maximum = inMax;
            _barHeater2.Minimum = inMin;
            _barHeater2.Maximum = inMax;
            _barHeater3.Minimum = inMin;
            _barHeater3.Maximum = inMax;
	    }

	    private void FrmMainClosing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			_adsClient.Dispose();
		}

		private void BtnReadClick(object sender, System.EventArgs e)
		{
			try
			{
				//read by handle
				TbHeaterState.Text = _adsClient.ReadAny(_hState, typeof(Boolean)).ToString();
                //FillStructControls((ComplexStruct)adsClient.ReadAny(hcomplexStruct, typeof(ComplexStruct)));
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void BtnWriteClick(object sender, System.EventArgs e)
		{
			try
			{
				//write by handle
				_adsClient.WriteAny(_hState, Boolean.Parse(TbHeaterState.Text));
                //adsClient.WriteAny(hcomplexStruct, GetStructFromControls())	;
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void BtnAddNotificationsClick(object sender, System.EventArgs e)
		{
			_arrNotificationHandles.Clear();
			try
			{
				//register notification            
                //notificationHandles.Add(adsClient.AddDeviceNotificationEx("MAIN.complexStruct1", AdsTransMode.OnChange, 100, 0, tbDint1, typeof(ComplexStruct)));
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			BtnDeleteNotifications.Enabled = true;
			BtnAddNotifications.Enabled = false;
		}

		private void BtnDeleteNotificationsClick(object sender, System.EventArgs e)
		{
			//delete registered notifications.
			try
			{
				foreach(int handle in _arrNotificationHandles)
					_adsClient.DeleteDeviceNotification(handle);
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			_arrNotificationHandles.Clear();
			BtnAddNotifications.Enabled = true;
			BtnDeleteNotifications.Enabled = false;
		}

        private void BtnPumpStateClick(object sender, EventArgs e)
        {
            //write by handle

            _adsClient.WriteAny(_hPumpState, true);
         }
            
        

	    private void AdsClientAdsNotificationEx(object sender, AdsNotificationExEventArgs e)
        {
            Type type = e.UserData.GetType();

            if (type == typeof(int))
            {
                int x = (int) e.UserData;
                
                if (x == _hState)
                {
                    _boPoolHeaterState = (bool) e.Value;
                    if (_boPoolHeaterState)
                        _txtPoolHeaterState.Text = "es ist eingeschaltet";
                    else
                        _txtPoolHeaterState.Text = "es ist ausgeschaltet";
                }
                else if (x == _hPumpState)
                {
                    _boPumpState = (bool)e.Value;
                    if (_boPumpState)
                        _btnPumpState.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(100))))); 
                    else
                        _btnPumpState.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
                }
                else if (x == _hHeater1)
                {
                    _labHeater1.Text = e.Value.ToString();
                    _barHeater1.Value = Convert.ToInt16(10 * (float)e.Value);
                }
                else if (x == _hHeater2)
                {
                    _labHeater2.Text = e.Value.ToString();
                    _barHeater2.Value = Convert.ToInt16(10*(float) e.Value);
                }
                else if (x == _hHeater3)
                {
                    _labHeater3.Text = e.Value.ToString();
                    _barHeater3.Value = Convert.ToInt16(10 * (float)e.Value);
                }
            }
            else if (type == typeof(TextBox))
            {
                var textBox = (TextBox)e.UserData;
                textBox.Text = e.Value.ToString();                
            }
        }

        

    

        //private void FillStructControls(ComplexStruct structure)
        //{
        //    tbComplexStruct_IntVal.Text = structure.intVal.ToString();
        //    tbComplexStruct_dintArr.Text = String.Format("{0:d}, {1:d}, {2:d}, {3:d}", structure.dintArr[0],
        //        structure.dintArr[1], structure.dintArr[2], structure.dintArr[3]);
        //    tbComplexStruct_boolVal.Text = structure.boolVal.ToString();
        //    tbComplexStruct_ByteVal.Text = structure.byteVal.ToString();
        //    tbComplexStruct_stringVal.Text = structure.stringVal;
        //    tbComplexStruct_SimpleStruct1_lrealVal.Text = structure.simpleStruct1.lrealVal.ToString();
        //    tbComplexStruct_SimpleStruct_dintVal.Text = structure.simpleStruct1.dintVal1.ToString();
        //}

        //private ComplexStruct GetStructFromControls()
        //{
        //    ComplexStruct structure = new ComplexStruct();
        //    String[] stringArr = tbComplexStruct_dintArr.Text.Split(new char[] {','});
        //    structure.intVal = short.Parse(tbComplexStruct_IntVal.Text);
        //    for(int i=0; i<stringArr.Length; i++)
        //        structure.dintArr[i] = int.Parse(stringArr[i]);
        
        //    structure.boolVal = Boolean.Parse(tbComplexStruct_boolVal.Text);
        //    structure.byteVal = Byte.Parse(tbComplexStruct_ByteVal.Text);
        //    structure.stringVal = tbComplexStruct_stringVal.Text;
        //    structure.simpleStruct1.dintVal1 = int.Parse(tbComplexStruct_SimpleStruct_dintVal.Text);
        //    structure.simpleStruct1.lrealVal = double.Parse(tbComplexStruct_SimpleStruct1_lrealVal.Text);
        //    return structure;
        //}		
	}

	[StructLayout(LayoutKind.Sequential, Pack=1)]
	public class SimpleStruct
	{
		public double lrealVal;
		public int dintVal1;
	}

	[StructLayout(LayoutKind.Sequential, Pack=1)]
	public class ComplexStruct
	{
		public short intVal;
		//specifies how .NET should marshal the array
		//SizeConst specifies the number of elements the array has.
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
		public int[] dintArr = new int[4];
		[MarshalAs(UnmanagedType.I1)]
		public bool boolVal;
		public byte byteVal;
		//specifies how .NET should marshal the string
		//SizeConst specifies the number of characters the string has.
		//'(inclusive the terminating null ). 
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
		public string stringVal = "";
		public SimpleStruct simpleStruct1 =new SimpleStruct();
	}
}
